/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.biz.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.thinkgem.jeesite.common.utils.*;
import com.thinkgem.jeesite.common.utils.excel.ExportCSV;
import com.thinkgem.jeesite.common.utils.excel.ExportExcel;
import com.thinkgem.jeesite.modules.biz.dao.BizBarcodeDao;
import com.thinkgem.jeesite.modules.biz.dao.BizStorageLocationDao;
import com.thinkgem.jeesite.modules.biz.entity.*;
import com.thinkgem.jeesite.modules.biz.service.BizBarcodeService;
import com.thinkgem.jeesite.modules.biz.service.BizGoodsService;
import com.thinkgem.jeesite.modules.biz.service.BizStockInDetailService;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.utils.LogUtils;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.modules.biz.service.BizStockInService;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 入库单的ControllerController
 * @author tianCheng
 * @version 2018-07-16
 */
@Controller
@RequestMapping(value = "${adminPath}/biz/bizStockIn")
public class BizStockInController extends BaseController {

	@Autowired
	private BizStockInService bizStockInService;
	@Autowired
	private BizStockInDetailService bizStockInDetailService;
	@Autowired
	private BizBarcodeService bizBarcodeService;
	@Autowired
	private BizBarcodeDao bizBarcodeDao;
	@Autowired
	private BizGoodsService bizGoodsService;
	@Autowired
	private BizStorageLocationDao bizStorageLocationDao;

	private static Logger log = LoggerFactory.getLogger(ExportExcel.class);

	@ModelAttribute
	public BizStockIn get(@RequestParam(required=false) String id) {
		BizStockIn entity = null;
		if (StringUtils.isNotBlank(id)){
			entity = bizStockInService.get(id);
		}
		if (entity == null){
			entity = new BizStockIn();
		}
		return entity;
	}
	
	@RequiresPermissions("biz:bizStockIn:view")
	@RequestMapping(value = {"list", ""})
	public String list(BizStockIn bizStockIn, HttpServletRequest request, HttpServletResponse response, Model model) {
		Page<BizStockIn> page = bizStockInService.findPage(new Page<BizStockIn>(request, response), bizStockIn); 
		model.addAttribute("page", page);
		return "modules/biz/bizStockInList";
	}

	@RequiresPermissions("biz:bizStockIn:view")
	@RequestMapping(value = "form")
	public String form(BizStockIn bizStockIn, Model model) {
		//获取入库单明细
		BizStockInDetail bizStockInDetail = new BizStockInDetail();
		bizStockInDetail.setStockInId(bizStockIn.getStockInId());
		//入库单明细
		List<BizStockInDetail> bizStockInDetailList = bizStockInDetailService.findListNo(bizStockInDetail);
		for (BizStockInDetail stockInDetail:bizStockInDetailList) {
			//查询入库单下面的条形码
			BizBarcode bizBarcode = new BizBarcode();
			bizBarcode.setStockInDetailId(stockInDetail.getStockInDetailId());
			List<BizBarcode> bizBarcodeList = bizBarcodeService.findList(bizBarcode);
			stockInDetail.setBizBarcodeNum(bizBarcodeList.size()+"");
			stockInDetail.setBizBarcodeList(bizBarcodeList);
		}
		model.addAttribute("bizStockIn", bizStockIn);
		model.addAttribute("bizStockInDetailList", bizStockInDetailList);
		return "modules/biz/bizStockInForm";
	}

	@RequiresPermissions(value={"biz:bizStockIn:add","biz:bizStockIn:edit"},logical= Logical.OR)
	@RequestMapping(value = "save")
	public String save(BizStockIn bizStockIn, Model model, RedirectAttributes redirectAttributes) {
		if (!beanValidator(model, bizStockIn)){
			return form(bizStockIn, model);
		}
		bizStockInService.save(bizStockIn);
		addMessage(redirectAttributes, "保存入库单成功");
		return "redirect:"+Global.getAdminPath()+"/biz/bizStockIn/?repage";
	}
	
	@RequiresPermissions("biz:bizStockIn:remove")
	@RequestMapping(value = "delete")
	public String delete(BizStockIn bizStockIn, RedirectAttributes redirectAttributes) {
		bizStockInService.delete(bizStockIn);
		addMessage(redirectAttributes, "删除入库单成功");
		return "redirect:"+Global.getAdminPath()+"/biz/bizStockIn/?repage";
	}

	@RequestMapping(value = "ajaxSave")
	public String ajaxSave(BizStockIn bizStockIn,Model model) {
		if(bizStockIn != null && StringUtils.isNotEmpty(bizStockIn.getStockInId())){
			//修改入库单的明细
			List<BizStockInDetail> detailList = bizStockIn.getBizStockInDetailList();
			//定义一个开关（是否是全部分配完托盘）
			boolean a = true;
			//当次入库单下面包含入库明细
			if(detailList != null && detailList.size() > 0){
				for (BizStockInDetail inDetail : detailList) {
					if(inDetail != null && StringUtils.isNotEmpty(inDetail.getStockInDetailId())){
						bizStockInDetailService.updateActualAmount(inDetail);
						//判断待分配托盘数大于0  说明分配有剩余数
						if(null != inDetail.getWaitDistributionAmount() && Integer.valueOf(inDetail.getWaitDistributionAmount()) > 0){
							a = false;
						}
						//入库的商品
						BizGoods goods = bizGoodsService.get(inDetail.getGoodsId());
						//添加入库单的条形码
						List<BizBarcode> bizBarcodeList = inDetail.getBizBarcodeList();
						if(null != bizBarcodeList){
							for (BizBarcode barcode:bizBarcodeList) {
								if(null != barcode && barcode.getNumber() != null && !barcode.getNumber().equals("") && !barcode.getNumber().equals("0")){
									//生成条形码
									Map<String,String> map = create(goods,inDetail,barcode);

									//添加条形码的信息
									barcode.setId(IdGen.uuid());
									barcode.setStockInDetailId(inDetail.getStockInDetailId());
									barcode.setName(map.get("code"));
									barcode.setUrl(map.get("path"));
									barcode.setGoodsId(inDetail.getGoodsId()); //商品的id
									barcode.setManufactureDate(inDetail.getManufactureDate()); //生产日期
									barcode.setStorageLocationId(inDetail.getStorageLocationId()); //库位id
									if(null != inDetail.getStorageLocationId()){
										BizStorageLocation bizStorageLocation = bizStorageLocationDao.get(inDetail.getStorageLocationId());
										if(null != bizStorageLocation){
											barcode.setStorageLocationName(bizStorageLocation.getName()); //库位name
										}
									}
									//barcode.setTxmPath(map.get("txmPath"));
									barcode.setCreateDate(new Date());
									barcode.setSurplusNumber(barcode.getNumber());
									barcode.setWaitNumber("0");
									barcode.setCreateBy(UserUtils.getUser());
									barcode.setCreateByName(UserUtils.getUser());
									bizBarcodeDao.insert(barcode);
								}
							}
						}
					}
				}
			}
			//修改入库单的状态
			if(a){
				bizStockIn.setStatus("1");
			}else{
				bizStockIn.setStatus("2");
			}
			bizStockInService.save(bizStockIn);
		}
		//return "redirect:"+Global.getAdminPath()+"/biz/bizStockIn/form?stockInId="+bizStockIn.getStockInId();
		return form(bizStockIn, model);
	}



	 /**
	  * 生成条形码的路径
	  * @author tiancheng
	  * @date 2018/9/5 14:02
	  * @param
	  * @return
	  */
	public String exportDir(){
		//默认传到系统管理员的明下
		String exportDir =  FileUtils.path(Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL + "1/files/exportFiles/" + DateUtils.getDate("yyyy-MM-dd") + "/");
		if (!new File(exportDir).exists()) {
			new File(exportDir).mkdirs();
		}
		return exportDir;
	}


	 /**
	  * 生成条形码
	  * @author tiancheng  
	  * @date 2018/9/5 15:17
	  * @param
	  * @return   
	  */  
	public Map create(BizGoods goods,BizStockInDetail inDetail,BizBarcode barcode){
		//返回的信息（条形码的批次号，条形码的url）
		Map<String,String> map = new HashMap();
		SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat si = new SimpleDateFormat("yyMMdd");
		String date = inDetail.getManufactureDate();

		String manufactureDate = inDetail.getManufactureDate();
		manufactureDate = manufactureDate.replaceAll("年","-");
		manufactureDate = manufactureDate.replaceAll("月","-");
		manufactureDate = manufactureDate.replaceAll("日","");
		String dayinDate = "";
		try {
			dayinDate = si.format(sim.parse(manufactureDate));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		//查询该生产日期下的商品是第几波生产条码
		BizBarcode bizBarcode = new BizBarcode();
		bizBarcode.setGoodsId(goods.getGoodsId());
		bizBarcode.setManufactureDate(date);
		//生成条形码(商品的编号+年月日(生产日期)+打印批次)
		Integer num = bizBarcodeDao.selectCountByGoodsId(bizBarcode);
		num += 1;
		String autoNum = num.toString();
		while (autoNum.length() < 4) {
			autoNum = "0" + autoNum;
		}
		String code = goods.getGoodsCode()+dayinDate+autoNum;
		//生成条形码的地址
		String txmPath = exportDir()+code+"TXM.jpg";
		//BarcodeUtil.generateFile(code,txmPath);
		BarcodeUtil.createBarcode(code, txmPath);

		//综合条形码的信息
		Map<String,String> mapInfo = new HashMap<>();
		//生成综合条形码的地址
		String path = exportDir()+code+".jpg";
		mapInfo.put("path",path);
		mapInfo.put("txmPath",txmPath);
		mapInfo.put("goodsCode",goods.getGoodsCode());
		if(null != inDetail.getManufactureDate()){
			mapInfo.put("manufactureDate",manufactureDate);
		}else{
			mapInfo.put("manufactureDate",null);
		}

		mapInfo.put("goodsName",goods.getGoodsName());
		mapInfo.put("piCi",goods.getGoodsCode()+dayinDate);
		mapInfo.put("goodsName",goods.getGoodsName());
		mapInfo.put("num",barcode.getNumber());
		WordToPic.TextToPic(mapInfo, 400, 200, 20);

		//删除单独的条形码(不能直接删除，跑定时)
		//FileUtils.delFile(txmPath);

		map.put("code",code);
		//path  去掉默认的部分路径
		if(path.indexOf("userfiles") != -1){
			String[] paths = path.split("userfiles");
			map.put("path","/userfiles"+paths[1]);
		}
		map.put("txmPath",txmPath);
		return map;
	}


	 /**
	  * 保存单个的条码
	  * @author tiancheng
	  * @date 2018/9/6 13:59
	  * @param barcodeId  条码的id
	  * @return
	  */
	 @RequestMapping(value = "saveBarcode")
	 @ResponseBody
	public String saveBarcode(String barcodeId,String stockInDetailId,String number){
		 try {
			 //查询入库单明细的信息
			 BizStockInDetail bizStockInDetail = bizStockInDetailService.get(stockInDetailId);
			 //判断待分配托盘数和此次修改的数量作比较
			 if(Integer.valueOf(bizStockInDetail.getWaitDistributionAmount()) == Integer.valueOf(number)){
				 bizStockInDetail.setWaitDistributionAmount("0");
				 bizStockInDetailService.updateActualAmount(bizStockInDetail);
				 //查询入库单是否还有剩余的为分配托盘的入库单明细
				 Integer num = bizStockInDetailService.selectCountByStockInId(bizStockInDetail.getStockInId());
				 if(num == 0){
					 //修改入库单的状态
					 BizStockIn bizStockIn = new BizStockIn();
					 bizStockIn.setId(bizStockInDetail.getStockInId());
					 bizStockIn.setStatus("1");
					 bizStockInService.updateStatus(bizStockIn);
				 }
			 }
			 //查询商品的信息
			 BizGoods goods = bizGoodsService.get(bizStockInDetail.getGoodsId());

			 //修改条形码的信息
			 BizBarcode barcode = bizBarcodeService.get(barcodeId);
			 barcode.setNumber(number);

			 //生成条形码
			 Map map = create(goods,bizStockInDetail,barcode);
			 barcode.setUrl((String) map.get("path"));
			 barcode.setTxmPath((String) map.get("txmPath"));
			 bizBarcodeService.save(barcode);

			 return  (String) map.get("path");
		 } catch (Exception e) {
			 e.printStackTrace();
		 }

		return null;
	}

	 /**
	  * 获取入库单的明细(批量打印时调用)
	  * @author tiancheng
	  * @date 2018/9/11 10:59
	  * @param
	  * @return
	  */
	@RequestMapping(value = "getInfo")
	@ResponseBody
	public List<Map> getInfo(String stockInId){
		//获取入库单的明细
		BizBarcode bizBarcode = new BizBarcode();
		bizBarcode.setStockInId(stockInId);
		List<Map> list = bizBarcodeDao.findListInfo(bizBarcode);
		if(list.size() > 0){
			for (Map map:list) {
				String manufactureDate = (String) map.get("manufactureDate");
				manufactureDate = manufactureDate.replaceAll("年","-");
				manufactureDate = manufactureDate.replaceAll("月","-");
				manufactureDate = manufactureDate.replaceAll("日","");
				map.put("manufactureDate",manufactureDate);
			}
		}
		return list;
	}


	/**
	 * 获取入库单的明细(单条打印时调用)
	 * @author tiancheng
	 * @date 2018/9/11 10:59
	 * @param
	 * @return
	 */
	@RequestMapping(value = "getInfoDan")
	@ResponseBody
	public Map getInfoDan(String id){
		BizBarcode bizBarcode = new BizBarcode();
		bizBarcode.setId(id);
		Map map = bizBarcodeDao.getInfo(bizBarcode);
		String manufactureDate = (String) map.get("manufactureDate");
		manufactureDate = manufactureDate.replaceAll("年","-");
		manufactureDate = manufactureDate.replaceAll("月","-");
		manufactureDate = manufactureDate.replaceAll("日","");
		map.put("manufactureDate",manufactureDate);
		return map;
	}


	/**
	 * 导出
	 * @author xuchen
	 * @date 2018/11/06 15:10
	 * @param
	 * @return
	 */
	@RequestMapping(value = "export", method = RequestMethod.POST)
	public String exportFile(BizStockIn bizStockIn, HttpServletRequest request,
							 HttpServletResponse response, RedirectAttributes redirectAttributes) {
		// 导出完毕提示的消息
		String msg = "";
		//记录日志操作
		String startOperation="开始进行入库单数据导出操作！";
		String endOperation="入库单数据导出操作结束！";
		User user = UserUtils.getUser();
		try {

			String fileNamePrefix = DateUtils.getDate("yyyyMMddHHmmss");// 导出文件名前缀
			List<String> fileNames = new ArrayList<String>(); // 存放生成的文件名称
			String exportDir = FileUtils.path(Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL + user.getId()
					+ "/files/exportFiles/" + DateUtils.getDate("yyyy-MM-dd") + "/");
			String filePath = exportDir + fileNamePrefix + "/";// 导出文件子目录
			if (!new File(filePath).exists()) {
				new File(filePath).mkdirs();
			}
			String zipFileName = fileNamePrefix + ".zip";// 压缩文件名称
			String zipFilePath = exportDir + zipFileName;// 压缩文件路径
			// 根据查询条件查询
			Page<BizStockInDetail> page = new Page<BizStockInDetail>();
			// 需要导出的数据总数目
			int dataSize = 0;
			try {
				// 获取商品列表的导出总条数
				List<BizStockInDetail> bizStockInDetailList = bizStockInDetailService.
						findListByParent(bizStockIn);
				dataSize = bizStockInDetailList.size();
			} catch (Exception e) {
				log.info("获取导出的数据总数目失败！失败信息：" + e.getMessage());
				LogUtils.saveLog(request, null, e, "获取导出的数据总数目失败！");
			}
			if (dataSize == 0) {
				msg = "导出失败！失败信息：导出数据为空";
				addMessage(redirectAttributes, "导出失败！失败信息：导出数据为空");
				log.info("导出失败！失败信息：导出数据为空");
				LogUtils.saveLog(request, user.getName() + "导出失败！失败信息：导出数据为空");
				return "redirect:"+Global.getAdminPath()+"/biz/bizStockIn/?repage";
			} else {// 5000数据分一个文件
				int fileSize = StringUtils.isBlank(Global.getConfig("exportExcel.fileSize")) ? 5000
						: Integer.parseInt(Global.getConfig("exportExcel.fileSize"));
				int fileNo = dataSize / fileSize + 1;
				for (int i = 1; i <= fileNo; i++) {
					page = bizStockInDetailService.findPageByParent(
							new Page<BizStockInDetail>(i, fileSize),
							bizStockIn);
					String fileName = fileNamePrefix + "-" + String.valueOf(i) + ".csv";
					fileNames.add(fileName);
					// 创建csv文件
					new ExportCSV(BizStockInDetail.class, 1).setDataList(page.getList()).writeFile(filePath + fileName);
				}
				System.out.println("需要压缩的文件所在目录：" + filePath);
				System.out.println("压缩文件所在目录：" + exportDir);
				System.out.println("压缩文件名称：" + zipFilePath);

				log.info(startOperation);
				log.info("操作人：" + UserUtils.getUser().getName());
				log.info("预计导出数据共" + dataSize + "条");

				FileUtils.zipFiles(filePath, "", zipFilePath);

				FileUtils.delFile(filePath);
				msg = "导出成功！共导出数据：" + dataSize + "条。" + "文件只保留" + Global.getConfig("userfiles.life") + "天，请尽快到“"
						+ "<a href='" + request.getContextPath() + Global.getAdminPath()
						+ "/../static/ckfinder/ckfinder.html' class='alert-link'>我的面板-文件管理</a>" + "”中下载！";
				addMessage(redirectAttributes,
						"导出成功！共导出数据：" + dataSize + "条。" + "文件只保留" + Global.getConfig("userfiles.life") + "天，请尽快到“"
								+ "<a href='" + request.getContextPath() + Global.getAdminPath()
								+ "/../static/ckfinder/ckfinder.html' style='color: white'>我的面板-文件管理</a>" + "”中下载！");
				log.info(endOperation);
				LogUtils.saveLog(request, user.getName() + "导出信息" + dataSize + "条");
			}
		} catch (Exception e) {
			msg = "导出失败！失败信息：" + e.getMessage();
			addMessage(redirectAttributes, "导出失败！失败信息：" + e.getMessage());
			log.info("导出失败！失败信息：" + e.getMessage());
			LogUtils.saveLog(request, null, e, user.getName() + "导出失败！");
		}
		return "redirect:"+Global.getAdminPath()+"/biz/bizStockIn/?repage";
	}
}